<?php

class Adept_Context implements ArrayAccess
{

    private static $instance = null;

    private $request;
    private $response;
    private $session;
    private $root;
    private $attributes = array();

    protected function __construct()
    {
    }

    /**
     * @return Adept_Context
     */
    public static function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new Adept_Context();
        }
        return self::$instance;
    }

    public function getRequest()
    {
        return $this->request;
    }

    public function setRequest($request)
    {
        $this->request = $request;
        $this->attributes['request'] = $request;
    }

    public function getResponse()
    {
        return $this->response;
    }

    public function setResponse($response)
    {
        $this->response = $response;
        $this->attributes['response'] = $response;
    }

    /**
     * @return Adept_Component_Root
     */
    public function getRoot()
    {
        return $this->root;
    }

    public function setRoot($root)
    {
        $this->root = $root;
    }

    public function getSession()
    {
        return $this->session;
    }

    public function setSession($session)
    {
        $this->session = $session;
    }

    public function getAttribute($key)
    {
        return $this->attributes[$key];
    }

    public function setAttribute($key, $value) {

        $this->attributes[$key] = $value;
    }

    public function hasAttribute($key)
    {
        return isset($this->attributes[$key]);
    }

    public function removeAttribute($key)
    {
        unset($this->attributes[$key]);
    }

    public function getAttributes()
    {
        return $this->attributes;
    }

    public function setAttributes($attributes)
    {
        $this->attributes = $attributes;
    }

    public function offsetGet($offset)
    {
        return $this->getAttribute($offset);
    }

    public function offsetSet($offset, $value)
    {
        $this->setAttribute($offset, $value);
    }

    public function offsetUnset($offset)
    {
        $this->removeAttribute($offset);
    }

    public function offsetExists($offset)
    {
        return $this->hasAttribute($offset);
    }

}
